<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <title>运动</title>
    <link rel="stylesheet" href="./00.css">
    <script crossorigin="anonymous"
        integrity="sha512-894YE6QWD5I59HgZOGReFYm4dnWc1Qt5NtvYSaNcOP+u1T9qYdvdihz0PPSiiqn/+/3e7Jo4EaG7TubfWGUrMQ=="
        src="//lib.baomitu.com/jquery/3.6.0/jquery.min.js"></script>
</head>

<body>
    <div class="box"></div>
    <div class="box1">碰撞</div>
    <div class="box2">下落</div>
    <div class="box3">扔球</div>
    <label>目标点 <input type="number" id="target" max="1500" step="1" /></label>
    <button>匀速</button>
    <button>缓冲</button>
    <button>弹性</button>
    <div class="tip">
        <span>音量</span>
    </div>
    <ul class="menu">
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
        <li class="active"></li>
    </ul>
    <div class="king">
        <ul>
            <li class="current">
                <a href="#">
                    <img src="./images/129.jpg" class="small" />
                    <img src="./images/129-freehover.png" class="big" />
                </a>
            </li>
            <li>
                <a href="#">
                    <img src="./images/152.jpg" class="small" />
                    <img src="./images/152-freehover.png" class="big" />
                </a>
            </li>
            <li>
                <a href="#">
                    <img src="./images/194.jpg" class="small" />
                    <img src="./images/194-freehover.png" class="big" />
                </a>
            </li>
            <li>
                <a href="#">
                    <img src="./images/195.jpg" class="small" />
                    <img src="./images/195-freehover.png" class="big" />
                </a>
            </li>
            <li>
                <a href="#">
                    <img src="./images/508.jpg" class="small" />
                    <img src="./images/508-freehover.png" class="big" />
                </a>
            </li>
        </ul>
    </div>
    <footer>拖拽可扔球</footer>
    <script>
        function get_style(dom, css) {
            if (window.getComputedStyle) {
                return window.getComputedStyle(dom, null)[css];
            } else {
                return dom.currentStyle(css);
            }
        }

        function uniform_motion(dom, target, speed) {
            // 匀速运动
            clearInterval(dom.timer);
            speed = target - dom.offsetLeft > 0 ? speed : -speed;
            dom.timer = setInterval(function () {
                if (Math.abs(target - dom.offsetLeft) < Math.abs(speed)) {
                    clearInterval(dom.timer);
                    dom.style.left = target + "px";
                } else {
                    dom.style.left = dom.offsetLeft + speed + "px";
                }
            }, 30);
        }

        function buffer_motion(dom, target) {
            // 缓冲运动
            clearInterval(dom.timer);
            dom.timer = setInterval(function () {
                var speed = (target - dom.offsetLeft) / 10;
                speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
                if (dom.offsetLeft == target) {
                    clearInterval(dom.timer);
                } else {
                    dom.style.left = dom.offsetLeft + speed + "px";
                }
            }, 30);
        }

        function dom_buffer(dom, css_obj, callback) {
            clearInterval(dom.timer);
            var offset, // 偏移量
                cur_value, // 当前值
                is_stop = true; // 是否可停止（计时器）
            dom.timer = setInterval(function () {
                for (var prop in css_obj) {
                    if (prop == "opacity") {    // 范围： 0 ~ 1
                        cur_value = parseFloat(get_style(dom, "opacity")) * 100;
                    } else {
                        cur_value = parseInt(get_style(dom, prop));
                    }
                    offset = (css_obj[prop] - cur_value) / 10;
                    offset = offset > 0 ? Math.ceil(offset) : Math.floor(offset); // 取整
                    if (prop == "opacity") {
                        dom.style.opacity = (cur_value + offset) / 100;
                    } else {
                        dom.style[prop] = cur_value + offset + "px";
                    }
                    if (cur_value != css_obj[prop]) is_stop = false; // 是否有一个未达到目标
                }
                if (is_stop) {
                    clearInterval(dom.timer);
                    typeof callback == "function" && callback();
                }
            }, 30);
        }

        function elastic(dom, target) {
            // 弹性运动
            clearInterval(dom.timer);
            var a,
                offset = 0;
            dom.timer = setInterval(function () {
                a = (target - dom.offsetLeft) * 0.6;
                offset += a;
                offset *= 0.85; // 模拟阻力
                dom.style.left = dom.offsetLeft + offset + "px";
                if (Math.abs(offset) <= 1 && Math.abs(target - dom.offsetLeft) <= 1) {
                    clearInterval(dom.timer);
                    dom.style.left = target + "px";
                }
            }, 30);
        }

        function collision(dom, offset_x, offset_y) {   // 弹性碰撞
            clearInterval(dom.timer)
            dom.timer = setInterval(function () {
                var new_left = dom.offsetLeft + offset_x,
                    new_top = dom.offsetTop + offset_y;
                if (new_left >= innerWidth - dom.offsetWidth) {
                    offset_x *= -1;
                    new_left = innerWidth - dom.offsetWidth;
                }
                if (new_left <= 0) {
                    offset_x *= -1;
                    new_left = 0  // 会到屏幕外，不影响滚动条
                }
                if (new_top >= innerHeight - dom.offsetHeight) {
                    offset_y *= -1;
                    new_top = innerHeight - dom.offsetHeight;
                }
                if (new_top <= 0) {
                    offset_y *= -1;
                    new_top = 0
                }
                dom.style.left = new_left + "px";
                dom.style.top = new_top + "px";
            }, 30);
        }

        function fall_collision(dom, offset_x, offset_y) {
            // 自由落体 + 弹性碰撞 + 能量损失
            var g = 3;  // 3 px/30ms2
            dom.timer = setInterval(function () {
                offset_y += g;
                var new_left = dom.offsetLeft + offset_x,
                    new_top = dom.offsetTop + offset_y;
                if (new_left >= innerWidth - dom.offsetWidth) {
                    offset_x *= -0.95;
                    offset_y *= 0.8;
                    new_left = innerWidth - dom.offsetWidth;
                }
                if (new_left <= 0) {
                    offset_x *= -0.95;
                    offset_y *= 0.8;
                    new_left = 0    // 这样就不会卡在墙里面
                }
                if (new_top >= innerHeight - dom.offsetHeight) {
                    offset_x *= 0.95;
                    offset_y *= -0.8;
                    new_top = innerHeight - dom.offsetHeight;
                }
                if (new_top <= 0) {
                    offset_x *= 0.95;
                    offset_y *= -0.8;
                    new_top = 0
                }
                if (Math.abs(offset_x) < 1) offset_x = 0;
                if (Math.abs(offset_y) < 1) offset_y = 0;
                if (
                    offset_x == 0 &&
                    offset_y == 0 &&
                    new_top == innerHeight - dom.offsetHeight
                ) {
                    clearInterval(dom.timer);
                } else {
                    dom.style.left = new_left + "px";
                    dom.style.top = new_top + "px";
                    var span = document.createElement('span')   // 显示轨迹
                    span.className = 'trajectory'
                    span.style.left = new_left + dom.offsetWidth * 0.5 + 'px'
                    span.style.top = new_top + dom.offsetHeight * 0.5 + 'px'
                    document.body.appendChild(span)
                }
            }, 30);
        }

        function throw_ball(dom) {
            dom.style.position = 'absolute'
            dom.style.cursor = 'move'
            dom.onmousedown = function (e) {
                clearInterval(dom.timer); // 只要一点击，就停止运动
                var dis_x = e.offsetX,
                    dis_y = e.offsetY;
                dom.last_x = 0; // 上次的坐标
                dom.last_y = 0;
                dom.offset_x = 0; // 和上次的差值
                dom.offset_y = 0;
                document.onmousemove = function (e) {
                    dom.style.left = e.pageX - dis_x + "px";
                    dom.style.top = e.pageY - dis_y + "px";
                    dom.offset_x = e.pageX - dom.last_x; // 计算差值
                    dom.offset_y = e.pageY - dom.last_y;
                    dom.last_x = e.pageX; // 更新坐标
                    dom.last_y = e.pageY;
                    // var span = document.createElement('span')   // 显示轨迹
                    // span.className = 'trajectory'
                    // span.style.left = e.pageX + 'px'
                    // span.style.top = e.pageY + 'px'
                    // document.body.appendChild(span)
                };
                document.onmouseup = function (e) {
                    document.onmousemove = null;
                    document.onmouseup = null;
                    fall_collision(dom, dom.offset_x, dom.offset_y);
                };
            };
        }

        var box = document.getElementsByClassName("box")[0],
            box1 = document.getElementsByClassName("box1")[0],
            box2 = document.getElementsByClassName("box2")[0],
            box3 = document.getElementsByClassName("box3")[0],
            move_btn = document.getElementsByTagName("button"),
            lis = document.getElementsByClassName('menu')[0].getElementsByTagName('li');
        key = true;

        move_btn[0].onclick = function () {
            uniform_motion(box, parseInt(target.value, 10) || 0, 10);
        };
        move_btn[1].onclick = function () {
            // buffer_motion(box, parseInt(target.value, 10) || 0);
            dom_buffer(box, { left: parseInt(target.value, 10) || 0 });
        };
        move_btn[2].onclick = function () {
            elastic(box, parseInt(target.value, 10) || 0);
        };
        var tip = document.getElementsByClassName("tip")[0];
        span = document.getElementsByTagName("span")[0];

        tip.onmouseenter = function () {
            dom_buffer(this, { left: 0, opacity: 100, height: 80, fontSize: 22 });
            dom_buffer(span, { "line-height": 80 });
        };
        tip.onmouseleave = function () {
            dom_buffer(this, { left: -390, opacity: 40, height: 50, fontSize: 15 });
            dom_buffer(span, { "line-height": 50 });
        };
        for (let i = 0; i < lis.length - 1; i++) {
            lis[i].onmouseenter = function () {
                elastic(lis[4], i * 150);
            };
        }

        box1.onclick = function () {
            collision(this, 7, 7);
        };

        box2.onclick = function () {
            fall_collision(this, 7, 0);
        };

        throw_ball(box3);

        $('.king li').mouseenter(function () {
            $(this).stop().animate({ width: 224 }).find('.big').stop().fadeIn().siblings('.small').stop().fadeOut()
            $(this).siblings().stop().animate({ width: 69 }).find('.big').stop().fadeOut().siblings('.small').stop().fadeIn()
        })
    </script>
</body>

</html>